﻿#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion

using System;
using System.IO;

namespace BitwiseOre.IO
{
    ///<summary>
    /// Provides a <see cref="Stream"/> that supports co-operative disconnections.
    ///</summary>
    public abstract class DisconnectableStream : Stream
    {
        /// <summary>
        /// Performs an orderly disconnection of the two sides of the interprocess
        /// communication channel.
        /// </summary>
        /// <exception cref="IOException">
        ///     An I/O error occured while disconnecting the stream. This is not an expected occurance.. 
        /// </exception>
        /// <exception cref="TimeoutException">
        ///     The operation timed out.
        /// </exception>
        public abstract void Disconnect();

        /// <summary>
        /// Begins an asychronous operation to perform an orderly disconnection of the
        /// two sides on the interprocess communication channel.
        /// </summary>
        /// <param name="callback">
        ///     An optional asynchronous callback, to be called when the disconnection is complete. 
        /// </param>
        /// <param name="state">
        ///     A user-provided object that distinguishes this particular asynchronous disconnect request
        ///     from other requests. 
        /// </param>
        /// <returns>
        ///    An <see cref="IAsyncResult"/> that represents this asynchonous operation.
        /// </returns>
        public abstract IAsyncResult BeginDisconnect(AsyncCallback callback, object state);

        /// <summary>
        /// Completes an asynchronous disconnection operation.
        /// </summary>
        /// <param name="asyncResult">
        ///     The asynchronous operation to complete. Must be the return value
        ///     from <see cref="BeginDisconnect"/>.
        /// </param>
        /// <exception cref="T:System.ArgumentNullException">
        ///     <paramref name="asyncResult"/> is null. 
        /// </exception>
        /// <exception cref="T:System.ArgumentException">
        ///     <paramref name="asyncResult"/> did not originate from a <see cref="BeginDisconnect"/> method 
        ///     on the current stream. 
        /// </exception>
        /// <exception cref="IOException">
        ///     An I/O error occured while disconnecting the stream. This is not an expected occurance.. 
        /// </exception>
        /// <exception cref="TimeoutException">
        ///     The operation timed out.
        /// </exception>
        public abstract void EndDisconnect(IAsyncResult asyncResult);

        /// <summary>
        /// Gets or sets a value, in millisecond, that determines how long the stream will attempt to 
        /// disconnect before timing out.
        /// </summary>
        /// <returns>
        ///     A value, in miliseconds, that determines how long the stream will attempt to disconnect before
        ///     timing out.
        /// </returns>
        public abstract int DisconnectTimeout { get; set; }
    }
}